package com.zhihuishu.micro.course.openapi.myuni.impl;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.able.openapi.zhsCourse.IOnlineSchoolForZhsCourseService;
import com.google.common.collect.Lists;
import com.zhihuishu.micro.course.dto.ChapterDto;
import com.zhihuishu.micro.course.dto.CourseCategoryDto;
import com.zhihuishu.micro.course.dto.CourseDto;
import com.zhihuishu.micro.course.dto.ScoreAssessRuleDto;
import com.zhihuishu.micro.course.log.LoggerCollectionEnum;
import com.zhihuishu.micro.course.log.MDCLoggerUtil;
import com.zhihuishu.micro.course.openapi.myuni.CourseOpenService;
import com.zhihuishu.micro.course.openapi.myuni.dto.CourseCategoryEnum;
import com.zhihuishu.micro.course.openapi.myuni.dto.CourseOpenDto;
import com.zhihuishu.micro.course.openapi.myuni.dto.CourseStatusEnum;
import com.zhihuishu.micro.course.openapi.myuni.dto.CourseTypeEnum;
import com.zhihuishu.micro.course.openapi.myuni.dto.CourseWebDto;
import com.zhihuishu.micro.course.openapi.myuni.dto.PageBean;
import com.zhihuishu.micro.course.openapi.myuni.dto.ScoreAssessRuleInterfaceDto;
import com.zhihuishu.micro.course.openapi.online.ChapterLessonOpenService;
import com.zhihuishu.micro.course.openapi.myuni.dto.CourseCategoryOpenDto;
import com.zhihuishu.micro.course.service.CategoryService;
import com.zhihuishu.micro.course.service.ChapterService;
import com.zhihuishu.micro.course.service.CourseService;
import com.zhihuishu.remote.ErrorCode;
import com.zhihuishu.remote.RemoteException;
import com.zhihuishu.remote.RemoteResult;
import com.zhihuishu.toolkit.helper.BeanHelper;

@Service("myuniCourseOpenService")
public class CourseOpenServiceImpl implements CourseOpenService {

    @Resource
    private CourseService courseService;

    @Resource
    private CategoryService categoryService;

    @Resource
    private ChapterService chapterService;

    @Resource
    private ChapterLessonOpenService chapterLessonOpenService;

    @Resource
    private IOnlineSchoolForZhsCourseService onlineSchoolForZhsCourseService;

    @Override
    public RemoteResult<Void> update(CourseWebDto course, long updateUser) throws RemoteException {

        RemoteResult<Void> result = new RemoteResult<Void>();
        // 参数检查
        if (course == null || course.getCourseId() == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.ARGUMENTS_ILLEGALITY);
            return result;
        }
        try {
            CourseDto dto = BeanHelper.transTo(course, CourseDto.class);
            // 如果传入了两项学时，更新总学时(Myuni接口调用时，会保证这两个参数要么都传入，要么都不传入)
            if (dto.getMeetCoursePeriod() != null && dto.getOnlineCoursePeriod() != null) {
                dto.setPeriod(dto.getMeetCoursePeriod() + dto.getOnlineCoursePeriod());// 总学时

            }
            // 默认为共享课程
            dto.setCourseOpener(2);
            // 若课程为微课，需默认创建一个章，并维护缓存
            if (dto.getType() != null && dto.getType() == 2) {
                List<Integer> chapterIds = chapterService.listChapterId(dto.getCourseId());
                if (chapterIds == null || chapterIds.size() == 0) {
                    ChapterDto chapterDto = new ChapterDto();
                    chapterDto.setCourseId(dto.getCourseId());
                    chapterDto.setIsDeleted(0);
                    chapterDto.setIsPass(1);
                    chapterDto.setRank(1);
                    Integer chapterId = chapterService.create(chapterDto, updateUser);
                    MDCLoggerUtil.saveLogger(String.format("接口保存章数据:%s", chapterDto), updateUser,
                            LoggerCollectionEnum.chapterCollection);
                    chapterDto.setId(chapterId);
                    chapterService.touchChapter(chapterId);
                   // chapterLessonOpenService.updateChapterRedis(chapterId);
                    chapterService.addChapterOnCourseRedis(dto.getCourseId(), chapterId);
                   // chapterLessonOpenService.addChapterOnCourseRedis(dto.getCourseId(), chapterId);
                }
            }
            // 更新课程
            courseService.update(dto, updateUser);
            // 更新课程分类(至少有一个传入值，才执行更新)
            if (course.getFirstId() != null || course.getSecondId() != null || course.getThirdId() != null) {
                // 根据原有课程分类，取第一条(通常只会有一组)
                List<CourseCategoryDto> categories = categoryService.listByCourse(course.getCourseId());
                CourseCategoryDto courseCategory = null;
                if (!CollectionUtils.isEmpty(categories)) {
                    courseCategory = categories.get(0);
                } else {
                    courseCategory = new CourseCategoryDto();
                }
                if (course.getFirstId() != null)
                    courseCategory.setFirstId(course.getFirstId());
                if (course.getSecondId() != null)
                    courseCategory.setSecondId(course.getSecondId());
                if (course.getThirdId() != null)
                    courseCategory.setThirdId(course.getThirdId());
                if (courseCategory.getId() != null) {

                    categoryService.updateCourseCategory(courseCategory);
                    categoryService.updateCCCategory(course.getCourseId());
                } else {
                    courseCategory.setCourseId(course.getCourseId());
                    categoryService.saveCourseCategory(courseCategory);
                    categoryService.saveCCCategory(courseCategory);
                }
            }
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("更新课程执行出错!");
        }

        return result;
    }

    /*
     * (非 Javadoc) <p>Title: update</p> <p>Description: </p>
     * 
     * @param courseOpenDto
     * 
     * @param updateUser
     * 
     * @return
     * 
     * @see
     * com.zhihuishu.micro.course.openapi.myuni.CourseOpenService#update(com.zhihuishu.micro.course
     * .openapi.myuni.dto.CourseOpenDto, long)
     */

    @Override
    public RemoteResult<Void> update(CourseOpenDto courseOpenDto, long updateUser) {
        RemoteResult<Void> remoteResult = new RemoteResult<Void>();
        try {
            // 参数检查
            if (courseOpenDto == null || courseOpenDto.getCourseId() == null
                    || courseOpenDto.getCourseCategoryEnum() == null
                    || courseOpenDto.getCourseTypeEnum() == null) {
                remoteResult.setSuccess(false);
                remoteResult.setErrorCode(ErrorCode.ARGUMENTS_ILLEGALITY);
                return remoteResult;
            }
            CourseDto dto = BeanHelper.transTo(courseOpenDto, CourseDto.class);
            // 默认为共享课程
            dto.setCourseOpener(2);
            dto.setCourseCategory(courseOpenDto.getCourseCategoryEnum().getCode());// 课程分类
            dto.setType(courseOpenDto.getCourseTypeEnum().getCode());// 课程类别
            // 如果传入了两项学时，更新总学时(Myuni接口调用时，会保证这两个参数要么都传入，要么都不传入)
            if (dto.getMeetCoursePeriod() != null && dto.getOnlineCoursePeriod() != null) {
                dto.setPeriod(dto.getMeetCoursePeriod() + dto.getOnlineCoursePeriod());// 总学时
            }
            // 更新课程
            courseService.update(dto, updateUser);
            MDCLoggerUtil.saveLogger(String.format("接口更新课程数据:%s", dto), updateUser,
                    LoggerCollectionEnum.courseCollection);
            // 若课程为微课，需默认创建一个章，并维护缓存
            if (dto.getType() != null && dto.getType() == 2) {
                List<Integer> chapterIds = chapterService.listChapterId(dto.getCourseId());
                if (chapterIds == null || chapterIds.size() == 0) {
                    ChapterDto chapterDto = new ChapterDto();
                    chapterDto.setCourseId(dto.getCourseId());
                    chapterDto.setIsDeleted(0);
                    chapterDto.setIsPass(1);
                    chapterDto.setRank(1);
                    Integer chapterId = chapterService.create(chapterDto, updateUser);
                    MDCLoggerUtil.saveLogger(String.format("接口保存章数据:%s", chapterDto), updateUser,
                            LoggerCollectionEnum.chapterCollection);
                    chapterDto.setId(chapterId);
                    chapterService.touchChapter(chapterId);
                   // chapterLessonOpenService.updateChapterRedis(chapterId);
                    chapterService.addChapterOnCourseRedis(dto.getCourseId(), chapterId);
                   // chapterLessonOpenService.addChapterOnCourseRedis(dto.getCourseId(), chapterId);
                }
            }

        } catch (Exception e) {
            remoteResult.setExceptionStack(e);
            remoteResult.setSuccess(false);
        }
        return remoteResult;
    }

    @Override
    public RemoteResult<Integer> create(int myuniCourseId,String name, long createUser, CourseTypeEnum courseTypeEnum)
            throws RemoteException {
        RemoteResult<Integer> result = new RemoteResult<Integer>();
        try {
            CourseDto course = courseService.create((long)myuniCourseId, name, createUser,
                    courseTypeEnum.getCode());
            MDCLoggerUtil.saveLogger(
                    String.format("创建课程:courseId=%d,courseName=%s", course.getCourseId(), course.getName()),
                    createUser, LoggerCollectionEnum.courseCollection);
            result.setResult(course.getCourseId().intValue());
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("创建课程执行出错!");
        }

        return result;
    }

    @Override
    public RemoteResult<Integer> queryCourseMode(long onlineCourseId) throws RemoteException {
        RemoteResult<Integer> result = new RemoteResult<Integer>();
        try {
            Integer courseMode = courseService.getCourseMode(onlineCourseId);
            result.setResult(courseMode);
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("查询课程模式执行出错!");
        }

        return result;
    }

    @Override
    public RemoteResult<Map<String, String>> queryExamTime(long onlineCourseId, Date courseStartTime)
            throws RemoteException {
        RemoteResult<Map<String, String>> result = new RemoteResult<Map<String, String>>();
        try {
            Map<String, String> daysMap = courseService.getStudyDays(onlineCourseId);
            int reviewOrExamDays = Integer.valueOf(daysMap.get("reviewOrExamDays"));
            int courseStudyDays = Integer.valueOf(daysMap.get("courseStudyDays"));
            Calendar c = Calendar.getInstance();
            c.setTime(courseStartTime);
            c.add(Calendar.DATE, courseStudyDays);
            Date startExamDate = c.getTime();
            c.setTime(startExamDate);
            c.add(Calendar.DATE, reviewOrExamDays);
            Date endExamDate = c.getTime();
            Map<String, String> map = new HashMap<String, String>();
            SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd");
            map.put("startExamDate", smf.format(startExamDate));
            map.put("endExamDate", smf.format(endExamDate));
            result.setResult(map);
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("查询课程考试时间执行出错!");
        }
        return result;
    }

    @Override
    public RemoteResult<ScoreAssessRuleInterfaceDto> queryScoreAssessRule(long onlineCourseId)
            throws RemoteException {
        RemoteResult<ScoreAssessRuleInterfaceDto> result = new RemoteResult<ScoreAssessRuleInterfaceDto>();
        try {
            ScoreAssessRuleDto scoreDto = courseService.queryScoreAssessRule(onlineCourseId);
            ScoreAssessRuleInterfaceDto interfaceDto = null;
            if (scoreDto != null) {
                interfaceDto = new ScoreAssessRuleInterfaceDto();
                interfaceDto.setBbsScore(scoreDto.getBbsScore());
                interfaceDto.setCourseId(scoreDto.getCourseId());
                interfaceDto.setFinalExamScoreShare(scoreDto.getFinalExamScoreShare());
                interfaceDto.setId(scoreDto.getId());
                interfaceDto.setMeetCourseScoreShare(scoreDto.getMeetCourseScoreShare());
                interfaceDto.setOnlineScoreShare(scoreDto.getOnlineScoreShare());
                result.setResult(interfaceDto);
            } else {
                result.setExceptionStack(new Exception("考核标准为空，传入参数onlineCourseId=" + onlineCourseId));
                result.setResult(null);
                result.setSuccess(false);
            }
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("查询查询考核标准执行出错!");
        }
        return result;
    }

    @Override
    public RemoteResult<Void> updateCourseState(long courseId, Integer state, long userId)
            throws RemoteException {
        RemoteResult<Void> result = new RemoteResult<Void>();
        try {
            courseService.updateCourseState(courseId, state, userId);
            MDCLoggerUtil.saveLogger(String.format("接口更新课程状态,courseId=%d,state=%d", courseId, state), userId,
                    LoggerCollectionEnum.courseCollection);
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("修改课程状态执行出错!");
        }

        return result;
    }

    @Override
    public RemoteResult<Void> deleteCourese(long courseId, long userId) {
        RemoteResult<Void> remoteResult = new RemoteResult<Void>();
        try {
            CourseDto courseDto = courseService.get(courseId);
            if (courseDto != null) {
                courseService.remove(courseId, userId);
                onlineSchoolForZhsCourseService.clearUserAuthorityCache(courseDto.getUserId());// 清除用户缓存
                MDCLoggerUtil.saveLogger(
                        String.format("myuni接口删除课程,courseId=%d,userId=%s", courseId, userId), userId,
                        LoggerCollectionEnum.courseCollection);
            }

        } catch (Exception e) {
            remoteResult.setExceptionStack(e);
            remoteResult.setSuccess(false);
        }
        return remoteResult;
    }

    @Override
    public RemoteResult<Integer> queryCourseCount(Integer schoolId, String name,
            CourseTypeEnum courseTypeEnum, CourseStatusEnum courseStatusEnum) {
        RemoteResult<Integer> remoteResult = new RemoteResult<Integer>();
        try {
            Assert.notNull(schoolId, "学校id不能为null");
            Integer courseType = null;
            int count;
            if (courseTypeEnum != null) {
                courseType = courseTypeEnum.getCode();
            }
            if (courseStatusEnum != null) {
                count = courseService
                        .queryCourseCount(schoolId, name, courseType, courseStatusEnum.getCode());
            } else {
                count = courseService.queryCourseCount(name, courseType, schoolId);
            }
            remoteResult.setResult(count);

        } catch (Exception e) {
            remoteResult.setSuccess(false);
            remoteResult.setExceptionStack(e);
        }
        return remoteResult;
    }

    @Override
    public RemoteResult<List<CourseCategoryOpenDto>> queryCourseCategoryByCourseIds(List<Long> courseIds) {
        RemoteResult<List<CourseCategoryOpenDto>> remoteResult = new RemoteResult<List<CourseCategoryOpenDto>>();
        try {
            Assert.notNull(courseIds, "courseId集合不能为null");
            Assert.notEmpty(courseIds, "集合不能为空");
            Assert.isTrue(!CollectionUtils.containsInstance(courseIds, null), "集合中的元素不能包含null");
            List<CourseCategoryDto> courseCategoryDtos = categoryService.listByCourse(courseIds);
            List<CourseCategoryOpenDto> courseCategoryOpenDtos = BeanHelper.transTo(courseCategoryDtos,
                    CourseCategoryOpenDto.class);
            remoteResult.setResult(courseCategoryOpenDtos);
        } catch (Exception e) {
            remoteResult.setSuccess(false);
            remoteResult.setExceptionStack(e);
        }
        return remoteResult;
    }

    @Override
    public RemoteResult<List<CourseOpenDto>> queryCourseInfoByCourseIds(Long... courseIds) {
        RemoteResult<List<CourseOpenDto>> remoteResult = new RemoteResult<List<CourseOpenDto>>();
        try {
            Assert.notNull(courseIds, "课程id集合不能为null");
            Assert.noNullElements(courseIds, "课程集合列表中不能包含为null的元素");
            List<CourseOpenDto> courseOpenDtos = Lists.newArrayList();
            CourseOpenDto courseOpenDto = null;
            List<Long> courseIdList = Arrays.asList(courseIds);
            List<CourseDto> courseDtos = courseService.findCourseDtoByList(courseIdList);
            for (CourseDto courseDto : courseDtos) {
                courseOpenDto = new CourseOpenDto();
                BeanHelper.copyProperties(courseDto, courseOpenDto);
                if (courseDto.getCourseCategory() != null) {
                    courseOpenDto.setCourseCategoryEnum(CourseCategoryEnum
                            .getCourseCategoryEnumByCode(courseDto.getCourseCategory()));
                }
                courseOpenDto.setCourseTypeEnum(CourseTypeEnum.getCourseTypeEnumByCode(courseDto.getType()));
                courseOpenDtos.add(courseOpenDto);
            }
            remoteResult.setResult(courseOpenDtos);
        } catch (Exception e) {
            remoteResult.setExceptionStack(e);
            remoteResult.setSuccess(false);
        }
        return remoteResult;
    }

    @Override
    public RemoteResult<List<CourseOpenDto>> queryCourseInfoByCond(Integer schoolId, String name,
            CourseTypeEnum courseTypeEnum, CourseStatusEnum courseStatusEnum, PageBean pageBean) {
        RemoteResult<List<CourseOpenDto>> remoteResult = new RemoteResult<List<CourseOpenDto>>();
        try {

            Assert.notNull(schoolId, "学校id不能为null");
            Integer courseType = null;
            List<Long> courseIds = Lists.newArrayList();
            List<CourseOpenDto> courseOpenDtos = Lists.newArrayList();
            if (courseTypeEnum != null) {
                courseType = courseTypeEnum.getCode();
            }
            if (courseStatusEnum != null) {
                courseIds = courseService.queryCourseIds(schoolId, name, courseType,
                        courseStatusEnum.getCode(), pageBean.getOffset(), pageBean.getLimit());
            } else {
                courseIds = courseService.queryCourseIds(name, courseType, schoolId, pageBean.getOffset(),
                        pageBean.getLimit());
            }
            if (courseIds != null && courseIds.size() > 0) {
                Long[] courseIdArray = new Long[courseIds.size()];
                courseIds.toArray(courseIdArray);
                courseOpenDtos = queryCourseInfoByCourseIds(courseIdArray).getResult();
            }
            remoteResult.setResult(courseOpenDtos);
        } catch (Exception e) {
            remoteResult.setSuccess(false);
            remoteResult.setExceptionStack(e);
        }

        return remoteResult;
    }

    @Override
    public RemoteResult<Integer> queryCourseLimitDay(long courseId) {
        RemoteResult<Integer> result = new RemoteResult<Integer>();
        try {
            Assert.notNull(courseId, "课程id不能为null");
            Map<String, String> daysMap = courseService.getStudyDays(courseId);
            if (daysMap != null) {
                result.setResult(Integer.valueOf(daysMap.get("courseStudyDays")));
            }
        } catch (Exception e) {
            result.setExceptionStack(e);
            result.setSuccess(false);
        }
        return result;
    }

}
